import sys
import math
import pickle
from .ledger import Ledger

data = None

class _brothel_data(list):
	_data = [
		{	'cost'		: 0,
			'upkeep'	: 50,
			'init_rooms'	: 3,
			'max_rooms'	: 12,
			'prestige'	: 0
		},

		{	'cost'		: 2000,
			'upkeep'	: 100,
			'init_rooms'	: 5,
			'max_rooms'	: 18,
			'prestige'	: 1
		},

		{	'cost'		: 5000,
			'upkeep'	: 200,
			'init_rooms'	: 8,
			'max_rooms'	: 25,
			'prestige'	: 2
		},

		{	'cost'		: 10000,
			'upkeep'	: 300,
			'init_rooms'	: 12,
			'max_rooms'	: 28,
			'prestige'	: 3
		},

		{	'cost'		: 25000,
			'upkeep'	: 550,
			'init_rooms'	: 18,
			'max_rooms'	: 36,
			'prestige'	: 4
		},

		{	'cost'		: 50000,
			'upkeep'	: 1000,
			'init_rooms'	: 20,
			'max_rooms'	: 52,
			'prestige'	: 5
		},
	]
	def __init__(self, *args, **kw):
		list.__init__(self, *args, **kw)
		self.extend(_brothel_data._data)

class _player_data(object):
	def __init__(self, *args, **kw):
		object.__init__(self, *args, **kw)
		self.reset()

	def reset(self):
#
#		floats for these so we can add tiny increments
#		for unhappy girls, for instance
#
		self.strength = 25.0
		self.disposition = 50.0

	def print_it(self):
		print "Player Data:"
		print ""
		print "Gold: {}".format(data.gold)
		print "Strength: {}".format(self.strength)
		print "Disposition: {}".format(self.disposition)
		print ""

	def rep_str(self):
		if self.strength > 100: self.strength = 100.0
		if self.strength < 0: self.strength = 0.0
		if self.disposition > 100: self.disposition = 100.0
		if self.disposition < 0: self.disposition = 0.0
		str = int(math.floor(self.strength/20))
		disp = int(math.floor(self.disposition/20))
		return _player_data.reps[str][disp]

#
#	changing reputation from vanilla wm
#
#	going to have 2 vars strength and disposition
#	strength goes from 0 (weak) to 100 (deadly)
#	disposition from 0 (saintly) to 100 (demonic)
#
#	we'll use the two variables to generate a
#	reputation string. That mixes up the rep a bit
#	and saves space on the stat panel
#
	reps = [
		# rep 0-20 helpless
		[ "Saint", "Nice Guy", "Victim", "Sneak", "Coward"],
		# rep 21-40 weak
		[ "Holy Fool", "Vigilant", "Respectable", "Crook", "Backstabber"],
		# rep 41-60 cabable
		[ "Crusader", "Upstanding", "Cabable", "Bravo", "Villain" ],
		# rep 61-80 strong
		[ "Champion", "Defender", "Tough Guy", "Crime Lord", "Savage" ],
		# rep 81-100 deadly
		[ "Paragon", "Hero", "Hardass", "Kingpin", "Scourge" ],
	]


class _game_data(object):
	def __init__(self, *args, **kw):
		object.__init__(self, *args, **kw)
		self.brothels = []
		self.reset()

	@property
	def num_brothels(self):
		return len(self.brothels)

	def current_brothel(self):
		return self.brothels[
			self.current_brothel_index
		]

	@property
	def gold(self):
		return self.ledger.gold

	def player_data(self):
		return self.player

	def reset(self):
		self.ledger = Ledger(self)
		self.brothels = []
		self.current_brothel_index = 0
		self.player = _player_data()
		self.dd = 1
		self.mm = 1
		self.yyyy = 1217
		self.day = 1

		self.player.reset()

	def print_it(self):
		print "Game Data:\n"
		print "Date: {0:02d}/{1:02d}/{2:04d}".format( 
			self.dd, self.mm, self.yyyy
		)
		print "Day: ", self.day
		print ""
		self.player.print_it()

		print ""
		print "{} Brothels:".format(len(self.brothels))
		
		for b in self.brothels:
			b.print_it()
			print ""

	def buy_brothel(self, name):
		index = len(self.brothels)
		if index == 6:
			print "error: already at max brothels"
			return
		b = Brothel()
		b.setup(name, index)
		self.brothels += [ b ]
		self.current_brothel_index = index
		print "setting current brothel index to ", index
		print "'brothels is now ", len(self.brothels)

	def current_brothel(self):
		if len(self.brothels) == 0:
			print "no brothels, returning none"
			return None
		return self.brothels[self.current_brothel_index]

	def next_brothel(self):
		self.current_brothel_index += 1
		if len(self.brothels) >= self.current_brothel_index:
			self.current_brothel_index = 0

	def prev_brothel(self):
		self.current_brothel_index -= 1
		if self.current_brothel_index <= 0:
			self.current_brothel_index = len(self.brothels) - 1


class Brothel(object):
	templates = None
	def __init__(self, *args, **kw):
		object.__init__(self, *args, **kw)

		self.name = "not named"
		self.fame = 0
		self.customer_satisfaction = 0
		self.rooms = 0
		self.max_rooms = 0
		self.dirt = 25
		self.beasts = []
		self.girls = []

		if Brothel.templates == None:
			Brothel.templates = _brothel_data()

	def print_it(self):
		print "Name: {}".format(self.name)
		print "Fame: {}".format(self.fame)
		print "Cust.Sat: {}".format(self.customer_satisfaction)
		print "Rooms: {} out of {}".format(
			self.rooms, self.max_rooms
		)
		print "Dirt: {}".format(self.dirt)
		print "Girls: {}".format(len(self.girls))
		print "Beasts: {}".format(len(self.beasts))

	def setup(self, name, index):
		self.name = name

		templ = Brothel.templates[index]
		self.fame = int(templ["prestige"] / 2)
		self.rooms = templ["init_rooms"]
		self.max_rooms = templ["max_rooms"]
		return True

	def girl_count(self):
		return len(self.girls)

	def girl_str(self):
		return "{}".format(len(self.girls))

	def happy_str(self):
		ival = self.customer_satisfaction
		if ival in range(-100, -80):
			return "Furious"
		if ival in range(-80, -60):
			return "Angry"
		if ival in range(-60, -40):
			return "Surly"
		if ival in range(-40, -20):
			return "Sullen"
		if ival in range(-20, 0):
			return "Unhappy"
		if ival in range(0, 20):
			return "Disappointed"
		if ival in range(20, 40):
			return "Neutral"
		if ival in range(20, 40):
			return "Content"
		if ival in range(40, 60):
			return "Happy"
		if ival in range(60, 80):
			return "Delighted"
		if ival in range(80, 101):
			return "Ecstatic"
		print "ival out of range for cust statisfaction: ", ival
		return "Delerious"

	def fame_str(self):
		ival = self.fame
		if ival == 0:
			return "Unknown"
		if ival in range(0, 20):
			return "Little Known"
		if ival in range(20, 40):
			return "Talked About"
		if ival in range(40, 60):
			return "Well Known"
		if ival in range(60, 80):
			return "Famous"
		if ival in range(80, 101):
			return "World Renowned"
		return "Notorious"

	def dirt_str(self):
		ival = self.dirt
		if ival == 0:
			return "Spotless"
		if ival in range(0, 20):
			return "Clean"
		if ival in range(20, 40):
			return "Passable"
		if ival in range(40, 60):
			return "Grubby"
		if ival in range(60, 80):
			return "Dirty"
		return "Filthy!"

	def beast_str(self):
		n = len(self.beasts)
		if n == 0:
			return "None"
		return "%d".format(n)

	def room_str(self):
		rooms = self.rooms
		max = self.max_rooms
		return "{} (max {})".format(rooms, max)

	def add(self, girl):
		print "adding {} to brothel".format(girl.name)
		self.girls.append(girl)

data = _game_data()

#
# make a time stamp string for the save file
# I could get this from the file metadata, but
# given that I'm going to be reading the file for the
# brothel name anyway...
#
def make_stamp():
	from datetime import datetime
#
#	get the time
#
	dt = datetime.now()
#
#	format the time in ISO format
#
	stamp = "{}".format(dt)
#
#	truncate the unhelpful fractional seconds
#	and return the result
#
	return "{0:<19.19}".format(stamp)

def save(filename):
#
#	open the file for writing
#
	with open(filename, "wb") as fd:
#
#		start by creating a dictionary with the 
#		first brothel name and a timestamp
#
		dict = {
			"name" 	: data.brothels[0].name,
			"stamp"	: make_stamp(),
			"file"	: filename
		}
#
#		now pickle the dict. This will let us
#		populate the table with the real names
#		of the brothels without having to unpickle
#		all the save data for each save
#
		pickle.dump(dict, fd)
#
#		now pickle the game data in its entirity
#
		pickle.dump(data, fd)

def load(file):
	global data
	temp = None
	d = {}
	print "loading '{}'".format(file)
	with open(file, "rb") as fd:
		d = pickle.load(fd)
		temp = pickle.load(fd)
		#print "loaded {}, {}". format(d, temp)
#
#	handle load failure. needs an error message
#
	if temp == None:
		print "temp == none"
		return None
	print "data loaded"
	data = temp
	data.print_it()
	return data


if __name__ == "__main__":
	print sys.argv[0]

	if len(sys.argv) > 0:
		load(sys.argv[1])
		sys.exit()

	data.buy_brothel("foo")
	data.buy_brothel("bar")
	data.buy_brothel("baz")
	data.print_it()

	save("test.sav")
	data.reset()
	data.buy_brothel("wibble")
	data.print_it()

	print "LOADING"
	load("test.sav")
	data.print_it()

